// sgu369
// 题意：
// 给定k(<=2*10^5)个二维坐标整点，坐标范围[-10^9, 10^9]。
// 现在每一次可以选择一个平行坐标轴的矩形，如果矩形的三个点都有，那么
// 可以加入第四个点，这样一直到不能操作为止，问最后一共有几个点。
//
// 题解：
// 其实这样不断扩展是一种联通关系。对于某个点，它沟通了它的x坐标和y坐标，
// 然后对于同列的y坐标和它的y坐标也相连，同行的x坐标和它的x坐标也相连。
// 这些坐标点的(x, y)对，最后肯定都是可以产生的。
//
// 那么我们就用并查集维护这些联通分量，然后对于每个联通分量算一下x, y坐标
// 的个数，假如说是tx, ty，那么最后对答案的贡献就是tx*ty。
//
// ml:run = $bin < input
// ml:ccf += -g
// ml:opt = 0
#include <iostream>
#include <algorithm>
#include <unordered_map>

struct data { int x, y; };

int const maxn = 200007;
int disx[maxn];
int disy[maxn];
int last[2 * maxn];
int father[2 * maxn];
data da[maxn];
data count[2 * maxn];
int k, lenx, leny, tot;

int get_father(int x)
{
    return x == father[x] ? x : (father[x] = get_father(father[x]));
}

void set_union(int x, int y)
{
    int tx = get_father(x);
    int ty = get_father(y);
    if (tx != ty) father[tx] = ty;
}

int idx(int t) { return std::lower_bound(disx, disx + lenx, t) - disx + 1; }
int idy(int t) { return std::lower_bound(disy, disy + leny, t) - disy + 1; }

int main()
{
    std::ios_base::sync_with_stdio(false);
    std::cin >> k;
    for (int i = 0; i < k; i++) {
        std::cin >> da[i].x >> da[i].y;
        disx[lenx++] = da[i].x;
        disy[leny++] = da[i].y;
    }
    std::sort(disx, disx + lenx);
    std::sort(disy, disy + leny);
    lenx = std::unique(disx, disx + lenx) - disx;
    leny = std::unique(disy, disy + leny) - disy;

    for (int i = 1; i <= lenx + leny; i++) father[i] = i;

    for (int i = 0; i < k; i++) {
        int tx = idx(da[i].x), ty = idy(da[i].y) + lenx;
        set_union(tx, ty);
        if (last[tx]) set_union(last[tx], ty);
        if (last[ty]) set_union(last[ty], tx);
        last[tx] = ty;
        last[ty] = tx;
    }

    for (int i = 1; i <= lenx + leny; i++)
        father[i] = get_father(father[i]);

    std::unordered_map<int, int> key;
    for (int i = 1; i <= lenx + leny; i++) {
        if (!key.count(father[i])) {
            key[father[i]] = ++tot;
        }
        int tid = key[father[i]];
        if (i <= lenx) count[tid].x++;
        else count[tid].y++;
    }
    long long ans = 0;
    for (int i = 1; i <= tot; i++)
        ans += (long long)count[i].x * (long long)count[i].y;
    std::cout << ans << "\n";
}

